package com.wei.czz.framework.common.controller;

import com.wei.czz.common.annotation.Auth;
import com.wei.czz.common.annotation.Resubmit;
import com.wei.czz.common.dto.admin.DictDto;
import com.wei.czz.common.dto.common.NameValue;
import com.wei.czz.common.dto.common.dict.DictPageEnumDto;
import com.wei.czz.common.enums.common.dict.DictEnum;
import com.wei.czz.common.jsr303.group.OrderSearch;
import com.wei.czz.common.jsr303.group.Save;
import com.wei.czz.common.jsr303.group.Update;
import com.wei.czz.common.property.BatchProperty;
import com.wei.czz.common.tool.PageDto;
import com.wei.czz.common.tool.Result;
import com.wei.czz.common.vo.common.UpdateStatusVo;
import com.wei.czz.common.vo.common.dict.DictFormVo;
import com.wei.czz.common.vo.common.dict.DictVo;
import com.wei.czz.framework.common.manager.DictManager;
import com.wei.czz.framework.common.service.DictService;
import lombok.AllArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * Created by IntelliJ IDEA.
 *
 * @author wei
 * date: 2022-08-13 19:46:35
 * className: DictController 系统字典操作请求接口类
 * version: 1.0
 * description:
 */
@RestController
@RequestMapping("/sys/dict")
@AllArgsConstructor
public class DictController {

    private static final Logger log = LoggerFactory.getLogger(DictController.class);

    private final BatchProperty batchProperty;

    private final DictService dictService;

    private final DictManager dictManager;

    /**
     * 保存系统字典数据接口
     * <p>
     * 调用方：
     *  1、浏览器-后台管理页面-字典管理页面-字典操作弹出框调用
     * <p>
     * 此接口会校验是否重复提交
     * @param dictVo 系统字典参数对象
     * @return 不返回数据
     */
    @Resubmit(message = "保存系统字典")
    @PostMapping("/save")
    @Auth(permit = "system:dict:save")
    public Result<Object> saveDict(@Validated(Save.class) @RequestBody DictVo dictVo) {
        log.info("开始保存系统字典数据业务。{}", dictVo);

        dictManager.saveDict(dictVo);

        log.info("保存系统字典数据业务结束");
        return Result.success();
    }

    /**
     * 分页查询系统字典数据列表接口
     * <p>
     * 调用方：
     *  1、浏览器-后台管理页面-字典管理页面调用
     * @param dictFormVo 字典查询参数的对象
     * @return 分页查询结果
     */
    @PostMapping("/page/list")
    @Auth(permit = "system:dict:list")
    public Result<PageDto<DictDto>> getPageDictList(@Validated(OrderSearch.class) @RequestBody DictFormVo dictFormVo) {
        log.info("开始分页查询系统字典数据列表业务。{}", dictFormVo);

        PageDto<DictDto> page = dictManager.getPageDictList(dictFormVo);

        log.info("分页查询系统字典数据列表业务结束");
        return Result.success(page);
    }

    /**
     * 获取系统字典管理页面枚举接口
     * @return 结果
     */
    @GetMapping("/page/param")
    @Auth(permit = "system:dict:list")
    public Result<DictPageEnumDto> getDictPageParam() {
        log.info("开始获取系统字典管理页面枚举业务");

        DictPageEnumDto dictPageEnumDto = dictManager.getDictPageParam();

        log.info("获取系统字典管理页面枚举业务结束");
        return Result.success(dictPageEnumDto);
    }

    /**
     * 查询字典类型列表接口
     * <p>
     * 调用方：
     *  1、浏览器-后台管理页面-字典管理页面调用
     *
     * @return 字典类型列表
     */
    @GetMapping("/type/list")
    @Auth(permit = "system:dict:list")
    public Result<List<NameValue<Integer>>> getDictTypeList() {
        log.info("开始查询字典类型列表业务");

        List<NameValue<Integer>> dictDtoList = DictEnum.getDictTypeList();

        log.info("查询字典类型列表业务结束");
        return Result.success(dictDtoList);
    }

    /**
     * 获取字典下一个默认排序等级接口
     * <p>
     * 调用方：
     *  1、浏览器-后台管理页面-字典管理页-字典操作弹出框中调用
     *
     * @return 下一个默认排序等级数据
     */
    @GetMapping("/next/sort")
    @Auth(permit = "system:dict:save")
    public Result<Integer> getNextSort() {
        log.info("开始获取字典下一个默认排序等级业务");

        Integer nextSort = dictService.getNextSort();

        log.info("获取字典下一个默认排序等级业务结束");
        return Result.success(nextSort);
    }

    /**
     * 修改系统字典数据接口
     * <p>
     * 调用方：
     *  1、浏览器-后台管理页面-字典管理页面-字典操作弹出框调用
     * <p>
     * 此接口会校验是否重复提交
     * @param dictVo 系统字典参数对象
     * @return 不返回数据
     */
    @Resubmit(message = "修改系统字典")
    @PostMapping("/update")
    @Auth(permit = "system:dict:update")
    public Result<Object> updateDict(@Validated(Update.class) @RequestBody DictVo dictVo) {
        log.info("开始修改系统字典数据业务。{}", dictVo);

        dictManager.updateDict(dictVo);

        log.info("修改系统字典数据业务结束");
        return Result.success();
    }

    /**
     * 修改字典状态接口
     * <p>
     * 调用方：
     *  1、浏览器-后台管理页面-字典管理页中调用
     * <p>
     * 此接口会校验是否重复提交
     * @param updateStatusVo 参数对象
     * @return 不返回数据
     */
    @Resubmit(message = "修改字典状态")
    @PostMapping("/update/status")
    @Auth(permit = "system:dict:update")
    public Result<Object> updateDictStatus(@Validated @RequestBody UpdateStatusVo updateStatusVo) {
        log.info("开始修改字典状态业务。{}", updateStatusVo);

        dictManager.updateDictStatus(updateStatusVo.getIdList().get(0), updateStatusVo.getStatus());

        log.info("修改字典状态业务结束");
        return Result.success();
    }

    /**
     * 批量删除系统字典数据接口
     * <p>
     * 调用方：
     *  1、浏览器-后台管理页面-字典管理页面调用
     * <p>
     * 此接口会校验是否重复提交
     * @param idList 字典主键列表
     * @return 不返回数据
     */
    @Resubmit(message = "删除系统字典")
    @DeleteMapping("/delete")
    @Auth(permit = "system:dict:delete")
    public Result<Object> deleteDict(@RequestBody List<Long> idList) {
        log.info("开始批量删除系统字典数据业务。idList={}", idList);

        if (batchProperty.getMaxSize() < idList.size()) {
            log.warn("批量删除系统字典数据接口，删除数据量超过设定阈值");
            return Result.clientFail("一次删除系统字典操作，最多允许同时删除" + batchProperty.getMaxSize() + "个字典");
        }

        dictManager.deleteDict(idList);

        log.info("批量删除系统字典数据业务结束");
        return Result.success();
    }
}
